with ada.text_io; use ada.Text_IO;
with ada.Strings; use ada.strings;
with ada.Strings.fixed; use ada.strings.fixed;

with ariane.maths.vector;
with ariane.maths.matrix.any;
with ariane.maths.matrix.square;
with ariane.maths.matrix.intf;
with ariane.maths.matrix.utility;

procedure test_maths_matrix is
  use type float;

  function floattostr(f : float) return string is
  begin
    return Trim(float'image(f), both);
  end floattostr;

  package imatrix is new ariane.maths.matrix.intf(float);
  use type imatrix.object;

  package mutil is new ariane.maths.matrix.utility(float, floattostr, imatrix);
  use mutil;


  package vector4 is new ariane.maths.vector(float, 4, 0.0);
  use type vector4.object;

  v1 : vector4.object := vector4.create((1.0,2.0,3.0,4.0));
  v2 : vector4.object := vector4.create((5.0,6.0,7.0,8.0));
  s : float := v1 * v2;

  package mat is new ariane.maths.matrix.any(float, 0.0, imatrix);
  use type mat.object;

  package sqrmat is new ariane.maths.matrix.square(component_t=>float,
                                                   dimension=>4,
                                                   one=>1.0,
                                                   zero=>0.0,
                                                   vector=>vector4,
                                                   imatrix=>imatrix);
  use type sqrmat.object;

  m1 : mat.object := mat.create((
    (1.0,2.0,3.0),
    (4.0,2.0,7.0),
    (5.0,7.0,2.0),
    (3.0,8.0,1.0)
   ));
  m2 : mat.object := mat.create((
    (3.0,1.0),
    (8.0,9.0),
    (2.0,6.0)
   ));
  m3 : mat.object := m1 * m2;
  m4 : mat.object := mat.create((
    (7.1,3.6),
    (-3.5,4.2),
    (5.7,-1.2),
    (-1.0,-2.2)
   ));
  m5 : mat.object := -m3 - m4;

  sm1 : sqrmat.object := sqrmat.create((
    (1.0,3.1,2.1,-2.0),
    (3.2,1.4,-5.6,9.1),
    (-2.1,1.4,5.7,-8.2),
    (7.6,-1.2,-4.5,6.7)
   ));
  v3 :vector4.object := sm1 * v1;
  v4 :vector4.object := v2 * sm1;

  sm2 : sqrmat.object := sm1.inverse;

begin
  put_line(float'image(s));
  put_line("m3 = ");
  for i in 1..m3.numrows loop
    for j in 1..m3.numcols loop
      put(float'image(m3.get(i,j))); put(",");
    end loop;
    new_line;
  end loop;

  put_line("m5 = ");
  for i in 1..m5.numrows loop
    for j in 1..m5.numcols loop
      put(float'image(m5.get(i,j))); put(",");
    end loop;
    new_line;
  end loop;

  put_line("m5(tostring) = ");
  put_line(tostring(m5));

  put_line("v3 = ");
  for i in 1..4 loop
    put(float'image(v3.get(i))); put(",");
  end loop;
  new_line;
  put_line("v4 = ");
  for i in 1..4 loop
    put(float'image(v4.get(i))); put(",");
  end loop;

  new_line;
  put_line("sm2(tostring) = ");
  put_line(tostring(sm2));
end test_maths_matrix;
